package com.wordlearning.third.audio.impl;

import com.wordlearning.third.audio.TtsException;
import com.wordlearning.third.audio.TtsOptions;
import com.wordlearning.third.audio.TtsService;
import org.json.JSONArray;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Kitten TTS服务实现类
 * 实现与Kitten TTS API的交互
 */
@Service
@Primary
public class KittenTtsServiceImpl implements TtsService {
    
    private static final Logger logger = LoggerFactory.getLogger(KittenTtsServiceImpl.class);
    
    // HTTP客户端
    private final HttpClient httpClient;
    
    // Kitten TTS API配置
    @Value("${third-party.kitten-tts.api-url:http://localhost:8000}")
    private String apiUrl;
    
    @Value("${third-party.kitten-tts.timeout:30000}")
    private int timeoutMs;
    
    /**
     * 构造函数
     * 初始化HTTP客户端
     */
    public KittenTtsServiceImpl() {
        this.httpClient = HttpClient.newBuilder()
                .connectTimeout(Duration.ofMillis(30000)) // 默认超时30秒
                .build();
    }
    
    /**
     * 构造函数，用于测试
     */
    public KittenTtsServiceImpl(String apiUrl, int timeoutMs) {
        this.apiUrl = apiUrl;
        this.timeoutMs = timeoutMs;
        this.httpClient = HttpClient.newBuilder()
                .connectTimeout(Duration.ofMillis(timeoutMs))
                .build();
    }
    
    @Override
    public List<String> getLanguages() throws TtsException {
        try {
            String languagesUrl = buildUrl("/api/languages");
            logger.debug("获取语言列表: {}", languagesUrl);
            
            HttpRequest request = HttpRequest.newBuilder()
                    .uri(URI.create(languagesUrl))
                    .timeout(Duration.ofMillis(timeoutMs))
                    .GET()
                    .header("Accept", "application/json")
                    .build();
            
            HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
            
            if (response.statusCode() == 200) {
                JSONObject jsonResponse = new JSONObject(response.body());
                if (jsonResponse.has("languages")) {
                    return jsonResponse.getJSONArray("languages").toList().stream()
                            .map(Object::toString)
                            .collect(Collectors.toList());
                } else {
                    throw TtsException.badRequest("Invalid response format: missing 'languages' field");
                }
            } else {
                handleErrorResponse(response);
                return Collections.emptyList(); // 不会执行到这里，handleErrorResponse会抛出异常
            }
        } catch (IOException | InterruptedException e) {
            throw TtsException.serviceUnavailable("Failed to connect to Kitten TTS API: " + e.getMessage());
        }
    }
    
    @Override
    public Map<String, String> getVoices(String language) throws TtsException {
        try {
            String voicesUrl = buildUrl("/api/voices");
            if (language != null && !language.trim().isEmpty()) {
                voicesUrl += "?language=" + language;
            }
            logger.debug("获取语音列表: {}", voicesUrl);
            
            HttpRequest request = HttpRequest.newBuilder()
                    .uri(URI.create(voicesUrl))
                    .timeout(Duration.ofMillis(timeoutMs))
                    .GET()
                    .header("Accept", "application/json")
                    .build();
            
            HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
            
            if (response.statusCode() == 200) {
                JSONObject jsonResponse = new JSONObject(response.body());
                if (jsonResponse.has("voices")) {
                    List<String> voices = jsonResponse.getJSONArray("voices").toList().stream()
                            .map(Object::toString)
                            .collect(Collectors.toList());
                    
                    Map<String, String> voiceMap = new HashMap<>();
                    for (String voice : voices) {
                        voiceMap.put(voice, formatVoiceName(voice));
                    }
                    return voiceMap;
                } else {
                    throw TtsException.badRequest("Invalid response format: missing 'voices' field");
                }
            } else {
                handleErrorResponse(response);
                return Collections.emptyMap(); // 不会执行到这里，handleErrorResponse会抛出异常
            }
        } catch (IOException | InterruptedException e) {
            throw TtsException.serviceUnavailable("Failed to connect to Kitten TTS API: " + e.getMessage());
        }
    }
    
    @Override
    public byte[] synthesize(String text, TtsOptions options) throws TtsException {
        if (text == null || text.trim().isEmpty()) {
            throw TtsException.badRequest("Text parameter is required");
        }
        
        if (options == null) {
            options = TtsOptions.defaultOptions();
        }
        
        // 验证语速参数
        if (options.getSpeed() <= 0) {
            throw TtsException.badRequest("Speed must be greater than 0");
        }
        
        try {
            String ttsUrl = buildUrl("/api/tts");
            logger.debug("调用TTS API: {}, 文本长度: {}, 语音: {}, 语速: {}, 语言: {}", 
                    ttsUrl, text.length(), options.getVoice(), options.getSpeed(), options.getLanguage());
            
            // 构建请求体
            JSONObject requestBody = new JSONObject();
            requestBody.put("text", text);
            requestBody.put("voice", options.getVoice());
            requestBody.put("speed", options.getSpeed());
            requestBody.put("language", options.getLanguage());
            
            // 创建HTTP请求
            HttpRequest request = HttpRequest.newBuilder()
                    .uri(URI.create(ttsUrl))
                    .timeout(Duration.ofMillis(timeoutMs))
                    .header("Content-Type", "application/json")
                    .header("Accept", "audio/wav")
                    .POST(HttpRequest.BodyPublishers.ofString(requestBody.toString(), StandardCharsets.UTF_8))
                    .build();
            
            // 发送请求并获取响应
            HttpResponse<byte[]> response = httpClient.send(request, HttpResponse.BodyHandlers.ofByteArray());
            
            if (response.statusCode() == 200) {
                logger.debug("TTS API调用成功，接收音频数据大小: {} 字节", response.body().length);
                return response.body();
            } else {
                handleErrorResponse(response);
                return new byte[0]; // 不会执行到这里，handleErrorResponse会抛出异常
            }
        } catch (IOException | InterruptedException e) {
            throw TtsException.serviceUnavailable("Failed to connect to Kitten TTS API: " + e.getMessage());
        }
    }
    
    @Override
    public Map<String, Object> getServiceInfo() throws TtsException {
        try {
            String serviceUrl = buildUrl("");
            logger.debug("获取服务信息: {}", serviceUrl);
            
            HttpRequest request = HttpRequest.newBuilder()
                    .uri(URI.create(serviceUrl))
                    .timeout(Duration.ofMillis(timeoutMs))
                    .GET()
                    .header("Accept", "application/json")
                    .build();
            
            HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
            
            if (response.statusCode() == 200) {
                JSONObject jsonResponse = new JSONObject(response.body());
                Map<String, Object> result = new HashMap<>();
                
                if (jsonResponse.has("message")) {
                    result.put("message", jsonResponse.getString("message"));
                }
                if (jsonResponse.has("version")) {
                    result.put("version", jsonResponse.getString("version"));
                }
                if (jsonResponse.has("endpoints")) {
                    result.put("endpoints", jsonResponse.getJSONArray("endpoints").toList());
                }
                
                return result;
            } else {
                handleErrorResponse(response);
                return Collections.emptyMap(); // 不会执行到这里，handleErrorResponse会抛出异常
            }
        } catch (IOException | InterruptedException e) {
            throw TtsException.serviceUnavailable("Failed to connect to Kitten TTS API: " + e.getMessage());
        }
    }
    
    /**
     * 构建完整的API URL
     */
    private String buildUrl(String path) {
        if (path == null || path.isEmpty()) {
            return apiUrl;
        }
        
        if (path.startsWith("/")) {
            path = path.substring(1);
        }
        
        if (apiUrl.endsWith("/")) {
            return apiUrl + path;
        } else {
            return apiUrl + "/" + path;
        }
    }
    
    /**
     * 格式化语音名称为更友好的显示名称
     */
    private String formatVoiceName(String voiceId) {
        // 简单的格式转换，例如 expr-voice-5-m -> Male Voice 5
        if (voiceId.contains("-f")) {
            return voiceId.replace("expr-voice-", "Female Voice ").replace("-f", "");
        } else if (voiceId.contains("-m")) {
            return voiceId.replace("expr-voice-", "Male Voice ").replace("-m", "");
        }
        return voiceId;
    }
    
    /**
     * 处理错误响应
     */
    private void handleErrorResponse(HttpResponse<?> response) throws TtsException {
        int statusCode = response.statusCode();
        String errorMessage = "API call failed with status code: " + statusCode;
        
        try {
            // 尝试安全地获取响应体作为字符串
            String errorBody = null;
            if (response.body() instanceof String strBody) {
                errorBody = strBody;
            } else if (response.body() instanceof byte[] byteBody) {
                errorBody = new String(byteBody, StandardCharsets.UTF_8);
            }
            
            if (errorBody != null) {
                logger.error("Kitten TTS API错误响应: {}", errorBody);
                
                // 尝试解析错误JSON
                try {
                    JSONObject errorJson = new JSONObject(errorBody);
                    if (errorJson.has("detail")) {
                        if (errorJson.get("detail") instanceof JSONObject) {
                            JSONObject detailObj = errorJson.getJSONObject("detail");
                            if (detailObj.has("error")) {
                                errorMessage = detailObj.getString("error");
                            }
                        } else {
                            errorMessage = errorJson.getString("detail");
                        }
                    }
                } catch (Exception e) {
                    // 解析失败时使用原始响应
                    errorMessage = errorBody;
                }
            }
        } catch (Exception e) {
            // 忽略解析错误
        }
        
        logger.error("Kitten TTS API调用失败: {}", errorMessage);
        
        if (statusCode >= 400 && statusCode < 500) {
            throw TtsException.badRequest(errorMessage);
        } else {
            throw TtsException.serverError(errorMessage);
        }
    }
}